package com.cy.lib.redis.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 没有用上锁
 * @author	ChenYu
 * @data	2016年7月6日 下午4:06:51
 * @Description ：重入锁、独占锁、乐观锁、读写锁
 */
public class LockUtils {

	static final ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<String, ReentrantLock>();

	// 取得锁
	public static ReentrantLock getLock(String key) {
		return locks.putIfAbsent(key, new ReentrantLock());
	}

	// 取得锁(一直等待)
	public static ReentrantLock lock(String key) {
		ReentrantLock lock = getLock(key);
		lock.lock();
		return lock;
	}

	// 取得锁(并且设置等待最大时间)
	public static ReentrantLock tryLock(String key, long time, TimeUnit TimeUnit)
			throws InterruptedException {
		ReentrantLock lock = getLock(key);
		boolean timeOut = lock.tryLock(time, TimeUnit);
		return (timeOut ? lock : null);
	}

	// 释放锁
	public static void unlock(String key) {
		ReentrantLock lock = getLock(key);
		if (lock.isHeldByCurrentThread()) {
			lock.unlock();
		}
	}

	public static void unlock(List<ReentrantReadWriteLock> locks) {
		for (ReentrantReadWriteLock lock : locks) {
			if (lock.isWriteLockedByCurrentThread()) {
				lock.writeLock().unlock();
			}
		}
	}

	public static List<ReentrantReadWriteLock> newReadWriteLocks() {
		return new ArrayList<ReentrantReadWriteLock>();
	}
        
        private static Map<String,ReentrantReadWriteLock> rwLockMap = new HashMap<String, ReentrantReadWriteLock>();
        
        public static ReentrantReadWriteLock getRWLock(String key){
            ReentrantReadWriteLock rwLock;
            if(!rwLockMap.containsKey(key)){
                rwLock = new ReentrantReadWriteLock();
                rwLockMap.put(key, rwLock);
            }else{
                rwLock = rwLockMap.get(key);
            }
            return rwLock;
        }
}
